{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[729, 217, 12, 17, 252, 72]\n"
     ]
    }
   ],
   "source": [
    "a = [0, 1, 2, 4, 6, 8]\n",
    "b = [9, 6, 2, 1, 6, 2]\n",
    "c = []\n",
    "\n",
    "for i in range(len(a)):\n",
    "    c.append(a[i]**2 + b[i]**3)\n",
    "\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([56.50444181, 19.81131377, 40.50367674, 88.89385767, 15.90557614,\n",
       "       51.11358852, 32.23234855, 44.30396267, 26.31485549, 85.66244152,\n",
       "       48.28923618, 82.74374477, 26.49448171,  6.80666776, 70.15921022,\n",
       "       68.94297453, 76.30081136, 33.03814153,  0.68807673, 55.7969612 ,\n",
       "       25.6782555 ,  7.70874708, 98.3186687 , 78.18572057, 96.24603639,\n",
       "        5.01681979, 39.32085545, 45.93241535, 22.67879282, 40.29977138,\n",
       "       11.24137863, 72.84676483, 87.1744044 , 73.4565162 , 43.77088976,\n",
       "       83.64095171, 84.25699322, 57.97513072, 98.22485819, 88.43801644,\n",
       "       20.46343868, 95.70645481, 68.90471423, 78.22974526, 94.00265939,\n",
       "       54.20339259, 86.72479921, 61.62933799, 99.61502016,  3.35591023,\n",
       "       80.69206865, 65.09414248, 65.41244969, 13.84734188, 54.67578772,\n",
       "       48.36560864, 88.71832459, 54.29880463, 63.85727473, 52.58355171,\n",
       "        3.37094453, 30.44644874, 10.04094979,  7.9484582 , 21.26812314,\n",
       "       53.99330067, 38.50846239, 51.83734777, 13.83255498, 54.43009488,\n",
       "       69.59259993, 44.95691008, 54.3990486 , 26.0769948 , 61.20083096,\n",
       "       26.54796138, 50.94525746, 55.68894586, 44.54958506, 96.02982839,\n",
       "       11.09188684, 29.59585074, 95.79928385, 88.54117807, 97.5253671 ,\n",
       "       24.17004942, 53.67766765, 23.41473876, 83.18920439, 53.71040929,\n",
       "       80.97062061, 17.79967938, 11.34803916, 42.4075115 ,  2.13372963,\n",
       "       20.88850288, 39.95183169, 20.89199989, 78.14470119, 13.11054744])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = np.empty((100, 2))\n",
    "x[:,0] = np.random.uniform(0, 100, size=100)\n",
    "x[:,1] = 0.75 * x[:,1] + 3 +np.random.normal(0, 10, size=100)\n",
    "\n",
    "x[:,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x8a22f28>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x[:,0], x[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def demean(x):\n",
    "    return x - np.mean(x, axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_demean = demean(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x8ef8ba8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x_demean[:,0], x_demean[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(w, x):\n",
    "    return np.sum((x.dot(w)**2)) / len(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "def df_math(w, x):\n",
    "    return x.T.dot(x.dot(w)) * 2 / len(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "def df_debug(w, x, epsilon=0.0001):\n",
    "    res =np.empty(len(w))\n",
    "    for i in range(len(w)):\n",
    "        w_1 = w.copy()\n",
    "        w_1[i] += epsilon\n",
    "        w_2 = w.copy()\n",
    "        w_2[i] -= epsilon\n",
    "        res[i] = (f(w_1, x) - f(w_2, x)) / (2 * epsilon)\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "def direction(w):\n",
    "    return w / np.linalg.norm(w)\n",
    "\n",
    "def gradient_ascent(df, x, initial_w, eta, n_iters = 10000, epsilon=0.00000001):\n",
    "    w= direction(initial_w)\n",
    "    cur_iter = 0\n",
    "    while cur_iter < n_iters:\n",
    "        gradient = df(w, x)\n",
    "        last_w = w\n",
    "        w = w + eta * gradient\n",
    "        w = direction(w)\n",
    "        if(abs(f(w, x) - f(last_w, x)) < epsilon):\n",
    "            break\n",
    "        cur_iter += 1\n",
    "    return w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.17355902, 0.98137547])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "initial_w = np.random.random(x.shape[1])\n",
    "initial_w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "eta = 0.001"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([nan, nan])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gradient_ascent(df_math, x_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
